home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 2
/
Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso
/
Pearls
/
comm
/
Envoy
/
Talk
/
talk.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-17
|
16KB
|
291 lines
/*************************************************************************
Talk Client written by Jeffrey A. Litz for Envoy Talk Service
litz@cs.uwp.edu -or- Jeff_Litz@EDTNG.Kenosha.WI.US
Copyright ©1994 JL Productions.
*************************************************************************/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/semaphores.h>
#include <envoy/nipc.h>
#include <envoy/services.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/nipc_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/services_pragmas.h>
#include <utility/tagitem.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/nipc_protos.h>
#include <clib/services_protos.h>
#include <clib/alib_protos.h>
#include <clib/alib_stdio_protos.h>
#include <string.h>
#define geta4 __builtin_geta4
void geta4(void);
#define TKCMD_TALK 1
#define TKCMD_ABORT 2
#define TKCMD_DATA 3
struct Library *SysBase,*DOSBase,*NIPCBase,*ServicesBase;
static UBYTE version[32] = {"$VER: Talk Client v1.2a"};
void _main(void)
{
struct RDArgs *lpargs;
void *entity, *dest, *a_entity;
struct Transaction *trans,*a_trans;
ULONG sigbit=0,sigbit2=0,waitmask,signal,howmany;
ULONG args[1];
BPTR input_w,output_w;
ULONG done=0;
UBYTE work_space[512],host_name[256],userinput[256];
struct MsgPort *port,*replyport;
struct StandardPacket *packet;
struct TagItem cetags[4],cbtags[2],ttags[3];
geta4();
SysBase = *((struct Library **)4L);
/* Initialize a bunch of stuff for setting up transactions */
cetags[0].ti_Tag=ENT_Name;
/* Assigned later */
// cetags[0].ti_Data=NULL;
cetags[1].ti_Tag=ENT_Public;
cetags[1].ti_Data=NULL;
cetags[2].ti_Tag=ENT_AllocSignal;
cetags[2].ti_Data=(ULONG) &sigbit;
cetags[3].ti_Tag=TAG_END;
cetags[3].ti_Data=0;
cbtags[0].ti_Tag=ENT_AllocSignal;
cbtags[0].ti_Data=(ULONG) &sigbit2;
cbtags[1].ti_Tag=TAG_END;
cbtags[1].ti_Data=0;
ttags[0].ti_Tag=TRN_AllocReqBuffer;
ttags[0].ti_Data=516;
ttags[1].ti_Tag=TRN_AllocRespBuffer;
ttags[1].ti_Data=4;
ttags[2].ti_Tag=TAG_END;
ttags[2].ti_Data=0;
/* open up dos library */
if(DOSBase=OpenLibrary("dos.library", 37L))
{
/* Check to see if a machine to talk to was specified */
args[0]=0;
if(lpargs=ReadArgs("Server/A",args,NULL))
{
/* open up nipc library */
if(NIPCBase=OpenLibrary("nipc.library", 0L))
{
/* open up services library */
if(ServicesBase=OpenLibrary("services.library", 37L))
{
/* create a "near" side entity - to SEND data to service */
if(entity=CreateEntityA((struct TagItem *) cbtags))
{
/* Find out exactly who WE are */
GetHostName(entity,host_name,255);
/* Setup our entity name */
cetags[0].ti_Data=(ULONG) "talk_back";
/* create a "far" side entity - to RECEIVE data from service */
if(a_entity=CreateEntityA((struct TagItem *) cetags))
{
/* create a transaction for sending data to service */
if(trans=AllocTransactionA((struct TagItem *) ttags))
{
/* Locate the service */
if(dest=FindServiceA((UBYTE *)args[0], "Talk_Service", entity, NULL))
{
/*
** OK - found, now setup a transaction to
** send to the talk service to request a
** talk with us
*/
*(ULONG *)(trans->trans_RequestData)=*(ULONG *)(trans->trans_ResponseData);
strcpy(((UBYTE *)trans->trans_RequestData+4),host_name);
trans->trans_ReqDataActual=strlen(host_name)+4;
trans->trans_Command=TKCMD_TALK;
trans->trans_Timeout=10;
DoTransaction(dest,entity,trans);
/* Was there any type of transaction error? */
if(trans->trans_Error==0)
{
/* Everything went OK, *PLUS* the person wishes to talk with us */
/* Open up the input and output windows */
if(output_w=(BPTR)Open("CON:0/0/640/150/Output Window",MODE_NEWFILE))
{
if(input_w=(BPTR)Open("CON:0/150/640/50/Input Window/CLOSE",MODE_NEWFILE))
{
/*
** Setup everything for reading
** from the input window using
** packets
*/
/* Create a packet for reading the keyboard */
if(packet=(struct StandardPacket *)AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR))
{
port=(struct MsgPort *) (((struct FileHandle *)((ULONG)input_w<<2))->fh_Type);
if(replyport=(struct MsgPort *) CreatePort(NULL,0))
{
packet->sp_Msg.mn_Node.ln_Name=(char *)&(packet->sp_Pkt);
packet->sp_Pkt.dp_Link=&(packet->sp_Msg);
packet->sp_Pkt.dp_Port=replyport;
packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
packet->sp_Pkt.dp_Arg1=34000;
SendPkt(&packet->sp_Pkt,port,replyport);
/*
** set the wait mask for a
** wait for character from
** the input window and for
** any incoming transactions
*/
waitmask = (1<<replyport->mp_SigBit) | (1<<sigbit);
while(!done)
{
signal = Wait(waitmask);
/* Was there keyboard input? */
if(signal & (1<<replyport->mp_SigBit))
{
/* check to make sure */
if(GetMsg(replyport))
{
/* check again */
if(packet->sp_Pkt.dp_Res1)
{
/* read the input */
if(!(howmany=Read(input_w,userinput,255)))
{
/* close gadget - signal shut down */
done=2;
} else
{
/* Send input to our output window and send a transaction to the service to be displayed on the other side */
userinput[howmany]=0;
sprintf(work_space,"(%s) %s\n",host_name,userinput);
Write(output_w,work_space,strlen(work_space));
trans->trans_Command=TKCMD_DATA;
*(ULONG *)(trans->trans_RequestData)=*(ULONG *)(trans->trans_ResponseData);
strcpy(((UBYTE *)trans->trans_RequestData+4),work_space);
trans->trans_ReqDataActual=strlen(work_space)+4;
trans->trans_Timeout=10;
DoTransaction(dest,entity,trans);
}
}
/* setup another packet for wait for character */
packet->sp_Pkt.dp_Port=replyport;
packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
packet->sp_Pkt.dp_Arg1=34000;
SendPkt(&packet->sp_Pkt,port,replyport);
}
}
/* was there a transaction? */
if(signal & (1<<sigbit))
{
/* get the transaction */
if(a_trans=GetTransaction(a_entity))
{
/* was it a data transaction or close down transaction */
if(a_trans->trans_Command == TKCMD_DATA)
{
Write(output_w,(UBYTE *)((UBYTE *)a_trans->trans_RequestData+4),a_trans->trans_ReqDataActual-4);
} else if(a_trans->trans_Command == TKCMD_ABORT)
{
done=1;
}
/* reply to the DoTransaction() from the other side */
ReplyTransaction(a_trans);
}
}
}
/* Attempt to clear out any "left over" packet messages */
while((ULONG *)GetMsg(replyport) != (ULONG *)&packet->sp_Msg);
DeletePort(replyport);
}
/* Free up packet allocation */
FreeMem(packet,(long)sizeof(struct StandardPacket));
}
/* close input and output windows */
Close(input_w);
}
Close(output_w);
}
/* If we initiated the close down - attempt to signal other side to prevent a "hang" */
if(done == 2)
{
/* Just trying to make sure the TKCMD_ABORT gets through */
howmany=4;
while(howmany--)
{
trans->trans_ReqDataActual=4;
trans->trans_Command=TKCMD_ABORT;
trans->trans_Timeout=10;
DoTransaction(dest,entity,trans);
if(trans->trans_Error == 0)
{
break;
}
}
}
} else if(trans->trans_Error == 1)
{
/* talk service already active */
FPrintf(Output(),"Busy - talk already in process.\n");
} else if(trans->trans_Error == 2)
{
/* we were either ignored or no one was available */
FPrintf(Output(),"No response from talk request.\n");
}
/* lose the service */
LoseService(dest);
} else
{
/* something drastically went wrong */
/* either machine doesn't exist or service isn't available on that machine */
FPrintf(Output(),"Unable to connect with the machine or service on that machine.\n");
}
/* free up the transaction allocation */
trans->trans_ReqDataLength = 516;
FreeTransaction(trans);
}
/* clean up - delete/close everything */
DeleteEntity(a_entity);
}
DeleteEntity(entity);
}
CloseLibrary(ServicesBase);
}
CloseLibrary(NIPCBase);
}
FreeArgs(lpargs);
} else
{
/* readargs failed - no machine name provided */
FPrintf(Output(),"Must provide a machine name to talk to.\n");
}
CloseLibrary(DOSBase);
}
}